--[[

  =======================
  Recruitment Enhancement
  =======================

  CanGuildInvite()
  
]]

RecruitmentEnhancement = LibStub("AceAddon-3.0"):NewAddon("RecruitmentEnhancement", "AceConsole-3.0", "AceEvent-3.0", "AceTimer-3.0", "AceComm-3.0", "AceSerializer-3.0")
local addon = RecruitmentEnhancement
local AceGUI = LibStub("AceGUI-3.0")
local DBIcon = LibStub("LibDBIcon-1.0")
local liac = LibStub("LibInternalAddonCooldown-1.0")

-- Locales
local L = LibStub("AceLocale-3.0"):GetLocale("RecruitmentEnhancement", true)

-- Local Data
local version = GetAddOnMetadata("RecruitmentEnhancement", "Version")
local mailIsOpen = false
local currentSelection = 0
local logEntry
local checkString
local correspondance = nil
local numApplicants = 0
local friends = {}
local friendsMessage = string.format(L["friendsMessage"],L["Recruitment Enhancement"] )
local remName = nil
local addName = nil
local mailSendTmpRecipient = nil
local mailSendTmpKey = nil
local area = nil

local realmName = GetRealmName()
local armoryLink = nil

local CorrespondenceFrameShown = 0
local CorrespondenceFrame

local onlineStatus
local onlineStatusText
local onlineApplicants = {}
local offlineApplications = {}
local onlineApplicantsCount = 0
local offlineApplicantsCount = 0
local offlineCount = 0
local allApplicants = {}
local allApplicantsCount = 0
local applicantsQueued = nil
local applicantsQueuedMsg = false
local tbl = {}
local pulldown = {}
local defaultMailBody = L["defaultMailBody"]
local defaultMailSubject = L["defaultMailSubject"]
local currentView = nil
local currentSelectedToon = nil
local runOneTime = false
local inviteToon = false
local language = GetDefaultLanguage("player")
local invitetime = nil
local curtime = nil
local tblCount = 0

local tmpAppFriends = {}
local tmpAppplicants = {}
local tmpDeleteApplicants = {}
local tmpAppplicantsCorrespondence = {}
local tmpQueue = {}
local tmpKey = nil
local tmpSubKey = nil
local tmpConvo = nil
local queueDelay = 20

local region
local language
local altlanguage

local regionLookup = {
  ["us"] = "US",
  ["eu"] = "EU",
  ["tw"] = "TW",
  ["kr"] = "KR",
}

local languageLookup = {
  ["us"] = "en",
  ["eu"] = "en",
  ["tw"] = "zh",
  ["kr"] = "ko",
}

local playerLocale = GetLocale();
local localeStatus = {
["frFR"] = false,
["deDE"] = false,
["enUS"] = true,
["koKR"] = false,
["zhCN"] = false,
["zhTW"] = false,
["ruRU"] = false,
["esES"] = false,
["esMX"] = false,
}

local RecruitmentEnhancement_defaults = {
  global = {
    -- Settings
    LibDBIcon = { hide = false }, -- By default our minimap is hidden
    autoAddRemoveToons = true, -- Option to add/remove applicants to your friends list automatically so you can check there online status
    gameRegion = "us", -- game region for wowarmory links
    gameLanguage = "en", -- game language for wowarmory links
    gameAltLanguage = "", -- alternative game language for wowarmory links when defaults dont work
    autoClearEmtpyApplicantArchive = true,
    enableInviteQueue = false,
    enableAutoWhisper = true,
    autoWhisperWelcomeMsg = L["Your application with {guild} has been approved! Welcome aboard.. invite inc"],
    enableBellSound = true,
    enableWhisperLogging = true,
    
    -- Defaults and Templates
    guildUrl = L["guildUrl"], -- default www.guild.com url
    selectedMailTemplate = nil, -- current selected template
    mailTemplates = {}, -- Mail Templates Table
    
    -- Logs & Archives
    recruitLog = {}, -- applicant log/archive
    mailCheckLog = {}, -- inbound mail log (so we know if we've picked up a mail)
    applicantQueue = {},
    applicantQueueLocked = 0,
    applicantConvo = {},
    
    -- Syncing Setup
    autoSyncSelectedApplicantArchive = true,
    autoSyncSelectedApplicantActive = true,
    autoSyncAllCurrentApplicantsOnLogin = false,
	}
}

function RecruitmentEnhancement:OnInitialize()

	self.db = LibStub("AceDB-3.0"):New("RecruitmentEnhancementDB", RecruitmentEnhancement_defaults)
  
  liac:AddCooldown("RecruitmentEnhancement", "InviteQueue", nil, 30)

  -- Mail Events
  self:RegisterEvent("MAIL_SHOW")
  self:RegisterEvent("MAIL_CLOSED")
  self:RegisterEvent("MAIL_SEND_SUCCESS")
  self:RegisterEvent("MAIL_FAILED")
  
  -- Friend Events
  self:RegisterEvent("FRIENDLIST_UPDATE")
  
  -- Recruitment Events
  self:RegisterEvent("LF_GUILD_RECRUITS_UPDATED");
  
  -- Whisper Logging
  if(addon.db.global.enableWhisperLogging == true)then
    self:RegisterEvent("CHAT_MSG_WHISPER");
    self:RegisterEvent("CHAT_MSG_WHISPER_INFORM");
  end

	-- LDB Launcher
	local reLDB = LibStub:GetLibrary("LibDataBroker-1.1"):NewDataObject(L["Recruitment Enhancement"], {
		type = "launcher",
		icon = "Interface\\Addons\\recruitmentenhancement\\Icons\\minimap.tga",
		OnClick = function(clickedframe, button)
      if(GetGuildInfo("player"))then
        if button == "RightButton" then
          RecruitmentEnhancement:BuildApplicantList()
          RecruitmentEnhancement:OutputApplicationList()
        else
          ToggleGuildFrame()
          GuildFrameTab5:Click()
          GuildInfoFrameTab3:Click()
        end
      end
		end,
		OnTooltipShow = function(tt)
			tt:AddLine(L["Recruitment Enhancement"])
			tt:AddLine(RecruitmentEnhancement:GetToolTip())
      tt:AddLine(L["Minimap Tooltip Line 3"])
      tt:AddLine(L["Minimap Tooltip Line 4"])
		end,
	})
  DBIcon:Register(L["Recruitment Enhancement"], reLDB, addon.db.global.LibDBIcon)
  
end

function RecruitmentEnhancement:OnEnable()
  -- Toggle Frame so we have our frames and everything in the background

  -- if not IsInGuild() then return end
  
  liac:AddCooldown("RecruitmentEnhancement", "InviteQueue", nil, 30)

  ToggleGuildFrame(3)
  RecruitmentEnhancement:ModifyGuildInfoButtons();
  
  -- Communications
  self:RegisterComm("REnhRequest", "OnCommsReceive")
  self:RegisterComm("REnhLog", "OnCommsReceive")
  self:RegisterComm("REnhQSync", "OnCommsReceive")
  self:RegisterComm("REnhQLock", "OnCommsReceive")

  -- Hooks
  hooksecurefunc("SendMailFrame_SendMail",  RecruitmentLogSend)
  hooksecurefunc("OpenMail_Update",  RecruitmentLogReceive)

  -- Get Current Number of Applicants and print the details
  numApplicants = GetNumGuildApplicants()
  if(numApplicants > 0)then
    if(addon.db.global.enableBellSound == true)then
      PlaySoundFile("Sound\\Doodad\\BellTollAlliance.wav")
    end
    DEFAULT_CHAT_FRAME:AddMessage("|cffff8800" .. L["Recruitment Enhancement"] .. " Notice:|r " .. RecruitmentEnhancement:GetToolTip())
  end
  
  -- Should or hide the minimap icon
  RecruitmentEnhancement:ToggleMinimapIcon()
  
  -- Time Functionality
  if(addon.db.global.autoSyncAllCurrentApplicantsOnLogin == true)then
    self:ScheduleTimer(SyncActiveApplicants, 30)
  end
  
  -- We want a slightly random queueDelay so we dont all whisper/invite someone at the same time
  queueDelay = tonumber(date("%S"))
  if(queueDelay < 20)then
    queueDelay = queueDelay + 20
  end
  
end

function RecruitmentEnhancement:OnDisable()
end

-- CALLBACKS AND HOOKS

function RecruitmentTabClicked()

  -- Tab Clicked
  local selectedTab = PanelTemplates_GetSelectedTab(GuildInfoFrame);
  if (CorrespondenceFrameShown == 1 and selectedTab ==3 and (currentView == "ConfirmDecline" or currentView == "ViewTemplate" or currentView == "ViewConfig" ))then return  end
  
  if(GetGuildInfo("player"))then
    -- Guild Panels etc
    if(runOneTime == false)then
      hooksecurefunc("GuildInfoFrame_Update",  RecruitmentTabClicked)
      hooksecurefunc("GuildFrame_TabClicked",  HideCorrespondenceFrame)
      hooksecurefunc("CloseGuildMenus",  HideCorrespondenceFrame)
      hooksecurefunc("HybridScrollFrame_Update",  ScrollingApplicantFrame)
      
      runOneTime = true
    end
  end

  -- Output Logging
  if(addon.db.global.frameTesting == true)then
    print("Tab was clicked")
    print("Selected Tab is:")
    print(selectedTab)
  end

  if CorrespondenceFrameShown == 1 then
    CorrespondenceFrame:Hide()
    CorrespondenceFrameShown = 0
  end

  if(selectedTab == 3)then
    RecruitmentEnhancement:ShowCorrespondenceFrame()
    RecruitmentEnhancement:UpdateApplicantButtons()
  else
    SetGuildApplicantSelection(0)
  end

end

function ScrollingApplicantFrame()
  if CorrespondenceFrameShown == 1 then
    RecruitmentEnhancement:UpdateApplicantButtons()
  end
end

function RecruitmentLogSend()

  recipient = SendMailNameEditBox:GetText()

  if(addon.db.global.recruitLog[recipient])then
    subject = SendMailSubjectEditBox:GetText()
    body = SendMailBodyEditBox:GetText()
    key = RecruitmentEnhancement:GetCurrentTime()
    sentTime = RecruitmentEnhancement:GetCurrentDateNice() .. " " .. RecruitmentEnhancement:GetCurrentTimeNice()
    
    -- Add some temp data to check that it sent ok
    mailSendTmpRecipient = recipient
    mailSendTmpKey = key
    
    -- Add our Table
    addon.db.global.recruitLog[recipient].sentMail[key] = {
      mailSent = sentTime,
      mailSender = UnitName("player"),
      mailSubject = subject,
      mailBody = body,
    }
  end

end

function RecruitmentLogReceive()

  -- Get Our mailId
  mailId = InboxFrame.openMailID
  if not(mailId)then return end

  -- Get Our Data
  sender = OpenMailSender:GetText()
  subject = OpenMailSubject:GetText()
  -- body = OpenMailBodyText:GetText() -- broken in 4.2
  local body, _, _, _ = GetInboxText(mailId); -- fix for 4.2

  -- If data is missing
  if not ( sender and subject and body)then return end

  if(addon.db.global.recruitLog[sender])then

    checkString = sender .. subject .. body
    if(addon.db.global.mailCheckLog[checkString])then return end

    key = RecruitmentEnhancement:GetCurrentTime()
    sentTime = RecruitmentEnhancement:GetCurrentDateNice() .. " " .. RecruitmentEnhancement:GetCurrentTimeNice()
    addon.db.global.recruitLog[sender].sentMail[key] = {
      mailSent = sentTime,
      mailSender = sender,
      mailSubject = subject,
      mailBody = body,
    }
    addon.db.global.mailCheckLog[checkString] = sender
  end

end

function HideCorrespondenceFrame()

  -- Function to Hide our Frame
  currentView = nil
  
  -- Debugging
  if(addon.db.global.frameTesting == true)then
    print("HideCorrespondenceFrame was called")
  end

  if CorrespondenceFrameShown == 1 then
    CorrespondenceFrame:Hide()
    CorrespondenceFrameShown = 0
  end
  -- Reset our Applicant Selection to force the user to re-click
  SetGuildApplicantSelection(0)
end

function SyncActiveApplicants()
  
  -- Trigger our Active Applicant Sync
  if not(UnitAffectingCombat("player"))then
    --print("Triggering Active Applicant Sync")
    addon:SendCommMessage("REnhRequest", "_ACTIVE_" , "OFFICER")
  else
    --print("Held off due to combat.. will resend in 30 seconds")
    addon:ScheduleTimer(SyncActiveApplicants, 30)
  end
  
end

function RecruitmentEnhancement:OnCommsReceive(prefix, message, distribution, sender)
  
  if not (message or prefix or sender) then return end
  if(UnitAffectingCombat("player"))then return end
  
  if(prefix == "REnhRequest") then
  
    tbl = {}
    
    -- Gather our Data
    if(message == "_ACTIVE_")then
      tbl = RecruitmentEnhancement:BuildActiveRecruitsSentMailTable()
    else
      tmpKey = "tmp_" .. message
      tbl[tmpKey] = RecruitmentEnhancement:BuildApplicantSentMailTable(message)
    end
    
    -- Send our Data
    self:SendCommMessage("REnhLog", self:Serialize(tbl), "OFFICER")
    
    -- Send our Queue as well
    tbl = {}
    
    -- Gather our Data
    tbl = RecruitmentEnhancement:QueueBuildTable()
    
    -- Send our Data
    self:SendCommMessage("REnhQSync", self:Serialize(tbl), "OFFICER")
    
  elseif(prefix == "REnhLog") then

    -- Process Our Data
    if(sender == UnitName("player"))then return end -- we dont care about our own cause we know we have those mails :D
    
    -- Deserialize Our Message
    local success, t = self:Deserialize(message)
    RecruitmentEnhancement:ConsolidateCorrespondence(t)
  
  -- REnhQLock
  elseif(prefix == "REnhQLock") then
    
    -- If it's ours then dont worry about it
    if(sender == UnitName("player"))then return end

    -- Someone has processed there Q and found someone, lets hold off on running ours
    addon.db.global.applicantQueueLocked = RecruitmentEnhancement:GetCurrentTime() + 90
    
  elseif(prefix == "REnhQSync") then

    -- Process Our Data
    if(sender == UnitName("player"))then return end -- we dont care about our own cause we know we have those in the queue :D
    
    -- Deserialize Our Message
    local success, t = self:Deserialize(message)
    RecruitmentEnhancement:QueueConsolidate(t)
    
  end

end

--|| EVENTS ||--

function RecruitmentEnhancement:MAIL_SHOW()

  mailIsOpen = true
  if CorrespondenceFrameShown == 1 then
    RecruitmentEnhancement:ShowCorrespondenceFrame()
  end
end

function RecruitmentEnhancement:MAIL_CLOSED()

  mailIsOpen = false
  if CorrespondenceFrameShown == 1 then
    RecruitmentEnhancement:ShowCorrespondenceFrame()
  end
end

function RecruitmentEnhancement:MAIL_SEND_SUCCESS()

  -- Send Successful /whoop
  mailSendTmpRecipient = nil
  mailSendTmpKey = nil

  if CorrespondenceFrameShown == 1 then
    RecruitmentEnhancement:ShowCorrespondenceFrame()
  end

end

function RecruitmentEnhancement:MAIL_FAILED()

  -- Our Send Failed :(
  if(addon.db.global.recruitLog[mailSendTmpRecipient])then
    if(addon.db.global.recruitLog[mailSendTmpRecipient].sentMail[mailSendTmpKey])then
      addon.db.global.recruitLog[mailSendTmpRecipient].sentMail[mailSendTmpKey] = nil
      mailSendTmpRecipient = nil
      mailSendTmpKey = nil
    end
  end
end

function RecruitmentEnhancement:FRIENDLIST_UPDATE()

  if(UnitAffectingCombat("player"))then return end
  if not(addon.db.global.autoAddRemoveToons == true)then return end

  friends = {}
  numFriends = GetNumFriends()
  if(numFriends > 0)then
    for i = 1, numFriends do
      local name, level, class, area, connected, status, note = GetFriendInfo(i);
      if(name)then
        friends[name] = note
      end
      i = i + 1
    end
  end

  -- Process our Queue (we only want it every 30 seconds)
  if(liac:GetCooldown("RecruitmentEnhancement", "InviteQueue", nil ) == 0)then
    RecruitmentEnhancement:QueueProcess() -- Process Our Queue
    RecruitmentEnhancement:CleanUpConvos() -- Process Our Cleanup of Convos
    RecruitmentEnhancement:CleanUpFriends() -- Process Our Cleanup of Friends
    if(addon.db.global.autoClearEmtpyApplicantArchive == true)then
      RecruitmentEnhancement:CleanUpArchives() -- Process Our Cleanup of Archives
    end
    liac:AddCooldown("RecruitmentEnhancement", "InviteQueue", nil, 30)
  end  
  
end

function RecruitmentEnhancement:LF_GUILD_RECRUITS_UPDATED()

  if not ( numApplicants ) then numApplicants = 0 end
  if ( GetNumGuildApplicants() >  numApplicants ) then
    if(addon.db.global.enableBellSound == true)then
      PlaySoundFile("Sound\\Doodad\\BellTollAlliance.wav")
    end
    DEFAULT_CHAT_FRAME:AddMessage("|cffff8800" .. L["Recruitment Enhancement"] .. " Notice:|r " .. RecruitmentEnhancement:GetToolTip())
  end
  
  RecruitmentEnhancement:ToggleMinimapIcon()

end

function RecruitmentEnhancement:CHAT_MSG_WHISPER(type, message, sender)

  -- is it a whisper?
  if not (type == "CHAT_MSG_WHISPER") then return end
  RecruitmentEnhancement:LogWhispers(message, sender, false)
  
end

function RecruitmentEnhancement:CHAT_MSG_WHISPER_INFORM(type, message, recipient)

    -- is it a whisper?
  if not (type == "CHAT_MSG_WHISPER_INFORM") then return end
  RecruitmentEnhancement:LogWhispers(message, recipient, true)
  
end

--|| RECRUITEMENT FUNCTIONS ||--
function RecruitmentEnhancement:UpdateApplicantButtons()

  local scrollFrame = GuildInfoFrameApplicantsContainer;
  local offset = HybridScrollFrame_GetOffset(scrollFrame);
  local buttons = scrollFrame.buttons;
  local numButtons = #buttons;
  local button, index, appstatus;
  realApplicants = 0
   
  for i = 1, numButtons do
      button = buttons[i];
      index = offset + i;
      local name, level, class, _, _, _, _, _, _, _, _, _, _, comment = GetGuildApplicantInfo(index);
      
      if ( name ) then
        appstatus = RecruitmentEnhancement:GetApplicantStatus(name)
        button.name:SetText(name .. appstatus);
        if (comment == "") then
          button.comment:SetText(L["Bad Applicant Comment"]);
        else
          button.comment:SetText(comment);
        end
      end
  end
     
end

function RecruitmentEnhancement:GetApplicantStatus(name)

  if not (name) then return end
  
  -- Define the color first
  status,area = RecruitmentEnhancement:CheckOnlineStatus(name)
  
  if(addon.db.global.autoAddRemoveToons == true and status == nil)then
    color = "|cffff0000"
  elseif(addon.db.global.autoAddRemoveToons == true and status == 1)then
    color = "|cff00ff00"
  else
    color = "|cffffff00"
  end
  
  -- If they are queued state that
  if(RecruitmentEnhancement:QueueCheck(name) == true)then
    return " ( " .. color .. L["Queued"] .. "|r )"
  end
  
  if(addon.db.global.recruitLog[name])then
    tbl = addon.db.global.recruitLog[name].sentMail
    if(RecruitmentEnhancement:CountTable(tbl) > 0)then
      return " ( " .. color .. L["Contacted"] .. "|r )"
    end
  end
  
  return " ( " .. color .. L["New!"] .. "|r )"
  
end

function RecruitmentEnhancement:ModifyGuildInfoButtons()

  if(GuildInfoFrameTab3)then

    -- Hook into our functions
    hooksecurefunc("GuildInfoFrameApplicants_Update",  RecruitmentTabClicked)

    -- Disable Bliz Buttons
    GuildRecruitmentInviteButton:Hide()
    GuildRecruitmentMessageButton:Hide()
    GuildRecruitmentDeclineButton:Hide()
  end

end

function RecruitmentEnhancement:PopulateRecruitMail()

  if(mailIsOpen == true)then

    -- Get our Data
    local playerName = UnitName("player")
    local guildName, guildRankName, guildRankIndex = GetGuildInfo("player");
    local guildUrl = self.db.global.guildUrl
    local name, level, class, _, _, _, _, _, isTank, isHealer, isDamage, comment = GetGuildApplicantInfo(GetGuildApplicantSelection());

    if(name)then
      -- Set Our Subject Data
      local template = addon.db.global.selectedMailTemplate
      local mailSubject = self.db.global.mailTemplates[template].subject
      mailSubject = string.gsub( mailSubject, L["{guild}"] , guildName);

      local mailBody = self.db.global.mailTemplates[template].body
      mailBody = string.gsub( mailBody, L["{guild}"] , guildName);
      mailBody = string.gsub( mailBody, L["{guildurl}"] , guildUrl);
      mailBody = string.gsub( mailBody, L["{player}"] , playerName);
      mailBody = string.gsub( mailBody, L["{rank}"] , guildRankName);

      SendMailNameEditBox:SetText(name);

      -- Set Our Subject
      SendMailSubjectEditBox:SetText(mailSubject);

      -- Set our Body
      SendMailBodyEditBox:SetText(mailBody);
      SendMailBodyEditBox:SetFocus();

      -- StationeryPopupFrame.selectedIndex = nil;
      SendMailFrame_Update();
      SendMailFrame_Update();
    end

  else
    DEFAULT_CHAT_FRAME:AddMessage(L["Recruitment Enhancement"] .. ": " .. L["You need your inbox open for this to work!"])
  end
end

function RecruitmentEnhancement:LogApplicationAction(name,subject,body)

  if(addon.db.global.recruitLog[name])then
    key = RecruitmentEnhancement:GetCurrentTime()
    sentTime = RecruitmentEnhancement:GetCurrentDateNice() .. " " .. RecruitmentEnhancement:GetCurrentTimeNice()
    addon.db.global.recruitLog[name].sentMail[key] = {
      mailSent = sentTime,
      mailSender = UnitName("player"),
      mailSubject = subject,
      mailBody = body,
    }
  end
  
end

function RecruitmentEnhancement:GuildInviteTable(tbl)

  if not tbl then return end
  
  -- reset variables
  offlineCount = 0
  applicantsQueued = nil
  applicantsQueuedMsg = false
  local guildName, guildRankName, guildRankIndex = GetGuildInfo("player");
  
  -- Loop Through our Invite Tabl
  for name, value in pairsByKeys(tbl) do
  
    -- Check our Online Status and decide if we should invite
    inviteToon = false
    if(addon.db.global.autoAddRemoveToons == false)then
      inviteToon = true
    else
      if RecruitmentEnhancement:CheckOnlineStatus(name) then
        inviteToon = true
      else
        applicantsQueuedMsg = true
        offlineCount = offlineCount+1
      end
    end
    
    -- If Invite Q'ing is enabled then just queue the toon (and save the processing for later)
    if (addon.db.global.enableInviteQueue == true and inviteToon == false)then

      -- Create a Log Record
      RecruitmentEnhancement:LogApplicationAction(name,L["Guild Invite Queued"],L["Guild Invite was Queued and they will be invited automatically when they are next online"])

      -- Add to our Q
      RecruitmentEnhancement:QueueAdd(name)

    else
      
      -- Def dont need this :)
      applicantsQueuedMsg = false

      if inviteToon == true then
        if(addon.db.global.recruitLog[name] and addon.db.global.autoAddRemoveToons == true)then

          RecruitmentEnhancement:LogApplicationAction(name,L["Guild Invite Sent"],L["Guild Invite was Sent and the player was online"])

        end
        if(addon.db.global.enableAutoWhisper == true)then
          msg = addon.db.global.autoWhisperWelcomeMsg
          msg = string.gsub( msg, L["{guild}"] , guildName);
          SendChatMessage(msg, "WHISPER", GetDefaultLanguage("player") , name)
        end
        GuildInvite(name)
      end
    
    end

  end
  
  -- If our we are queueing and flagged to show msg
  if(applicantsQueuedMsg == true)then
    return L["Some Recruits were offline and were queued"]
  end

  if(offlineCount > 0)then
    return L["Some Recruits were offline"]
  end

end

function RecruitmentEnhancement:GetMailTemplatePulldown()

  pulldown = {}
  foundTemplate = false
  tbl = addon.db.global.mailTemplates

  if(tbl)then
    for key, value in pairsByKeys(tbl,function(a,b) return b < a end) do
      pulldown[key] = key
      foundTemplate = true
    end
  end
  
  if (foundTemplate == false) then
    addon.db.global.mailTemplates["Default"] = {
      subject = defaultMailSubject,
      body = defaultMailBody
    }
  end

  return pulldown

end

function RecruitmentEnhancement:GetApplicantArchivePulldown()

  pulldown = {}
  tbl = addon.db.global.recruitLog

  if(tbl)then
    for key, value in pairsByKeys(tbl,function(a,b) return b < a end) do
      pulldown[key] = key
    end
  end

  return pulldown

end

function RecruitmentEnhancement:BuildRecruitCorrespondence(recipient,comment)

  region = addon.db.global.gameRegion
  language = addon.db.global.gameLanguage
  altlanguage = addon.db.global.gameAltLanguage
  
  if(altlanguage ~= nil and altlanguage ~= "")then language = string.lower(altlanguage) end
  
  correspondance = ""
  nocorrespondance = "\n\n                                     " .. L["No Correspondence"]

  if not(recipient) then return "\n\n                                     " .. L["Select Applicant"] end -- recipient not present
  if not(addon.db.global.recruitLog[recipient])then return nocorrespondance end -- recipient not in Log

  if(comment ~= '' and comment ~= nil)then
    correspondance = correspondance .. "----------------------------------------------------------------------------------\n"
    correspondance = correspondance .. "                               " .. L["APPLICATION COMMENT"] .. "\n"
    correspondance = correspondance .. "----------------------------------------------------------------------------------\n\n"
    correspondance = correspondance .. comment .. "\n\n"
  end

  armoryLink = "http://" .. region .. ".battle.net/wow/" .. language .. "/character/" .. realmName .. "/" .. recipient .. "/simple"
  armoryLink = string.gsub( armoryLink, "'" , "" );
  armoryLink = string.lower( armoryLink );
  if(armoryLink)then
    correspondance = correspondance .. "----------------------------------------------------------------------------------\n"
    correspondance = correspondance .. "                                   " .. L["ARMORY LINK"] .. "\n"
    correspondance = correspondance .. "----------------------------------------------------------------------------------\n\n"
    correspondance = correspondance .. armoryLink .. "\n\n"
  end
  

  recruitLog = addon.db.global.recruitLog[recipient].sentMail
  if(recruitLog)then
    for key, value in pairsByKeys(recruitLog,function(a,b) return b < a end) do
      if ( type(value) == "table" ) then
        mailSent = value.mailSent
        mailSender = value.mailSender
        mailSubject = value.mailSubject
        mailBody = value.mailBody

        correspondance = correspondance .. "----------------------------------------------------------------------------------\n"
        correspondance = correspondance .. "   " .. L["Sent"] .. ": " .. mailSent .. "                  " .. L["Sender"] .. ": " .. mailSender .. "\n"
        correspondance = correspondance .. "----------------------------------------------------------------------------------\n\n"
        correspondance = correspondance .. mailBody .. "\n\n"

      end
    end
  end

  if (correspondance == "") then correspondance = nocorrespondance end

  return correspondance
end

function RecruitmentEnhancement:CheckOnlineStatus(toon)

  numFriends = GetNumFriends()
  if(numFriends > 0)then
    for i = 1, numFriends do
      local name, level, class, area, connected, status, note = GetFriendInfo(i);
      if(name == toon and connected)then
        return 1 , area
      end
      i = i + 1
    end
  end
  return nil, nil

end

function RecruitmentEnhancement:BuildApplicantList()
  
  -- Make sure we have asked for our applicants
  RequestGuildApplicantsList();
  
  allApplicants = {}
  onlineApplicants = {}
  offlineApplications = {}
  allApplicantsCount=0
  onlineApplicantsCount = 0
  offlineApplicantsCount = 0

  numApplicants = GetNumGuildApplicants()
  for i = 1, numApplicants do
    local name, level, class, _, _, _, _, _, isTank, isHealer, isDamage, comment = GetGuildApplicantInfo(i);
    
    allApplicants[name] = true
    allApplicantsCount = allApplicantsCount+1
    
    if(RecruitmentEnhancement:CheckOnlineStatus(name))then
      onlineApplicants[name] = true
      onlineApplicantsCount = onlineApplicantsCount+1
    else
      offlineApplications[name] = true
      offlineApplicantsCount = offlineApplicantsCount+1
    end
    
    i = i+1
  end
  
end

function RecruitmentEnhancement:OutputApplicationList(option)

  if(option)then
    option = string.upper(option)
  end
  
  local msg_ln2 = L["Total Applicants"] .. ": " .. onlineApplicantsCount + offlineApplicantsCount
  local msg_ln3 = L["Online"] .. ": " .. onlineApplicantsCount .. " , " .. L["Offline"] .. ": " .. offlineApplicantsCount
  local msg_ln4 = L["Online Applicants"] .. ": " .. RecruitmentEnhancement:ConvertTableKeys2CSV(onlineApplicants)

  if(option)then
    SendChatMessage(" --- " .. L["Recruitment Enhancement"] .. " --- ", option);
    SendChatMessage(msg_ln2, option);
    SendChatMessage(msg_ln3, option);
    SendChatMessage(msg_ln4, option);
  else
    DEFAULT_CHAT_FRAME:AddMessage("|cffff8800" .. L["Recruitment Enhancement"] .. "|r")
    DEFAULT_CHAT_FRAME:AddMessage(msg_ln2)
    DEFAULT_CHAT_FRAME:AddMessage(msg_ln3)
    DEFAULT_CHAT_FRAME:AddMessage(msg_ln4)
  end
  
end

function RecruitmentEnhancement:ToggleMinimapIcon()
  -- Check and Update our Icon
  numApplicants = GetNumGuildApplicants()
  if(numApplicants > 0)then
    DBIcon:Show(L["Recruitment Enhancement"])
  else
    DBIcon:Hide(L["Recruitment Enhancement"])
  end
  
end

function RecruitmentEnhancement:GetToolTip()
  numApplicants = GetNumGuildApplicants()
  if(numApplicants == 0)then
    msg = L["No Applicants"]
  elseif(numApplicants == 1)then
    msg = L["You have a pending applicant"]
  elseif(numApplicants > 1)then
    msg = string.format( L["You have x pending applicants"] , numApplicants )
  end
  return msg
end

function RecruitmentEnhancement:CleanUpFriends()

  if(liac:GetCooldown("RecruitmentEnhancement", "InviteQueue", nil ) > 0)then
    return
  end

  -- Refresh Friends
  ShowFriends()

  tmpAppFriends = {}

  -- Cycle Through Your Friends List
  numFriends = GetNumFriends()
  if(numFriends > 0)then
    for i = 1, numFriends do
      local name, level, class, area, connected, status, note = GetFriendInfo(i);
      
      -- If the note matches our "friendsMessage"
      if(name and note == friendsMessage)then
        -- Add to the tmpAppFriends
        tmpAppFriends[name] = name
      end
      i = i + 1
    end
  end
  
  -- Go through our Applicants
  numApplicants = GetNumGuildApplicants()
  if(numApplicants > 0)then
    for i = 1, numApplicants do
      local name, level, class, _, _, _, _, _, isTank, isHealer, isDamage, comment = GetGuildApplicantInfo(i);
      
      -- If the applicant still exists
      if(name and tmpAppFriends[name])then
        -- remove them from the tempAppFriends table
        tmpAppFriends[name] = nil
      end
      
      i = i+1
    end
  end

  -- Loop through friends that are left
  if(tmpAppFriends)then
    for key,value in pairsByKeys(tmpAppFriends) do
      RemoveFriend(key)
    end
  end
  
  -- Refresh Friends
  ShowFriends()
  
end

function RecruitmentEnhancement:CleanUpArchives()
  
  if(addon.db.global.autoClearEmtpyApplicantArchive == false)then return end

  tbl = addon.db.global.recruitLog
  tmpDeleteApplicants = {}
  tmpAppplicants = {}
  
  numApplicants = GetNumGuildApplicants()
  if(numApplicants > 0)then
    for i = 1, numApplicants do
      local name, level, class, _, _, _, _, _, isTank, isHealer, isDamage, comment = GetGuildApplicantInfo(i);
      tmpAppplicants[name] = name
      i = i+1
    end
  end

  -- Loop through applicants
  if(tbl)then
    for applicant,value in pairsByKeys(tbl) do
      if not (tmpAppplicants[applicant])then
        tmpDeleteApplicants[applicant] = true
        if ( type(value) == "table" ) then
          for k,v in pairsByKeys(value.sentMail) do
            tmpDeleteApplicants[applicant] = nil
          end
        end
      end
    end
  end
  
  if(tmpDeleteApplicants)then
    for applicant,value in pairsByKeys(tmpDeleteApplicants) do
      addon.db.global.recruitLog[applicant] = nil
    end
  end

end

function RecruitmentEnhancement:BuildActiveRecruitsSentMailTable()
  RecruitmentEnhancement:BuildApplicantList()
  
  tmpAppplicants = {}
  if(allApplicants)then
    for key, value in pairsByKeys(allApplicants) do
      tmpAppplicants[key] = RecruitmentEnhancement:BuildApplicantSentMailTable(key)
    end
  end

  return tmpAppplicants
end

function RecruitmentEnhancement:BuildApplicantSentMailTable(recipient)
  
  tmpAppplicantsCorrespondence = {}
  if not(addon.db.global.recruitLog[recipient])then return end -- recipient not in Log

  recruitLog = addon.db.global.recruitLog[recipient].sentMail
  if(recruitLog)then
    for key, value in pairsByKeys(recruitLog) do
      if ( type(value) == "table" ) then
        mailSent = value.mailSent
        mailSender = value.mailSender
        mailSubject = value.mailSubject
        mailBody = value.mailBody
        
        tmpKey = "tmp_" .. key
        tmpAppplicantsCorrespondence[tmpKey] = {
          sent = mailSent,
          sender = mailSender,
          subject = mailSubject,
          body = mailBody,
        }

      end
    end
  end

  return tmpAppplicantsCorrespondence
end

function RecruitmentEnhancement:ConsolidateCorrespondence(tbl)

  if not tbl then return end
  
  for applicant, mails in pairsByKeys(tbl) do

    -- Gives me my applicant Name
    tmpKey = string.gsub( applicant, "tmp_" , "");
  
    -- If our Applicant doesn't exist create the table
    if not(addon.db.global.recruitLog[tmpKey])then addon.db.global.recruitLog[tmpKey] = { sentMail = {} } end 
    
    if(mails)then
      for key, value in pairsByKeys(mails) do
        -- our actual key
        tmpSubKey = string.gsub( key, "tmp_" , "");
        tmpSubKey = tonumber(tmpSubKey)
      
        -- If our Applicant doesn't exist create the table
        if not(addon.db.global.recruitLog[tmpKey].sentMail[tmpSubKey])then
        
          addon.db.global.recruitLog[tmpKey].sentMail[tmpSubKey] = {
            mailSent = value.sent,
            mailSender = value.sender,
            mailSubject = value.subject,
            mailBody = value.body,
          }
        
        end 
        
      end
    end
    
  end
  
end

function RecruitmentEnhancement:QueueAdd(name)

  if not(addon.db.global.autoAddRemoveToons == true)then return end
  when = RecruitmentEnhancement:GetCurrentTime()
  addon.db.global.applicantQueue[name] = when

end

function RecruitmentEnhancement:QueueRemove(name,when)
  
  if(when)then
    -- print(when)
  end
  
  if not(addon.db.global.autoAddRemoveToons == true)then return end
  if(addon.db.global.applicantQueue[name])then
    addon.db.global.applicantQueue[name] = nil
  end

end

function RecruitmentEnhancement:QueueCheck(name)

  if(addon.db.global.applicantQueue[name])then
    return true
  else
    return false
  end

end

function RecruitmentEnhancement:QueueProcess()

  if(liac:GetCooldown("RecruitmentEnhancement", "InviteQueue", nil ) > 0)then return end

  if not(addon.db.global.autoAddRemoveToons == true)then return end
  tbl = {}
  msg = nil
  local guildName, guildRankName, guildRankIndex = GetGuildInfo("player");
  invitetime = RecruitmentEnhancement:GetCurrentTime()
  
  if(invitetime > addon.db.global.applicantQueueLocked)then
    addon.db.global.applicantQueueLocked = 0
  else
    return
  end
  
  RecruitmentEnhancement:BuildApplicantList()
  
  tmpAppplicants = {}
  if(allApplicants)then
    for key, value in pairsByKeys(allApplicants) do
      tmpAppplicants[key] = key
    end
  end

  if(addon.db.global.applicantQueue)then
    for name,when in pairsByKeys(addon.db.global.applicantQueue) do
      -- If the person in the q is no longer an applicant
      if not(tmpAppplicants[name])then
        -- Remove them
        RecruitmentEnhancement:QueueRemove(name,"Q Process - no tmpApplicants")
        if(addon.db.global.autoAddRemoveToons == true)then
          liac:AddCooldown("RecruitmentEnhancement", "InviteBlocked", name, 15)
          RemoveFriend(name)
        end
      else
        if(RecruitmentEnhancement:CheckOnlineStatus(name))then
          
          -- If when == 0 then we add a delay to the invite/whisper
          if(when == 0)then
             -- Add 20 seconds to our current time (delay)
            addon.db.global.applicantQueue[name] = invitetime + queueDelay
            
          -- If our "when" is less than current time then we can process them
          elseif(when < invitetime) then
            RecruitmentEnhancement:LogApplicationAction(name,L["Guild Invite Sent"],L["Guild Invite was Sent and the player was online"])
            if(addon.db.global.enableAutoWhisper == true)then
              msg = addon.db.global.autoWhisperWelcomeMsg
              msg = string.gsub( msg, L["{guild}"] , guildName);
              SendChatMessage(msg, "WHISPER", GetDefaultLanguage("player") , name)
            end
            GuildInvite(name)
            self:SendCommMessage("REnhQLock", "1", "OFFICER")
            -- REMOVED BECAUSE THIS SHOULD CLEAN ITSELF UP ANYWAYS
            -- RecruitmentEnhancement:QueueRemove(name,"Should Have Invited Them >" .. when)
            addon.db.global.applicantQueue[name] = invitetime + 120 -- Delay the next invite for 2 mins

          end

        else
          -- reset our when flag to 0 if they are not online
          addon.db.global.applicantQueue[name] = 0
        end
      end
    end
  end
  
  ShowFriends()
  
end

function RecruitmentEnhancement:QueueBuildTable()
  tmpQueue = {}
  if(addon.db.global.applicantQueue)then
    for name,when in pairsByKeys(addon.db.global.applicantQueue) do
      tmpKey = "tmp_" .. name
      tmpQueue[tmpKey] = 0
    end
  end
  return tmpQueue
end

function RecruitmentEnhancement:QueueConsolidate(tbl)

  if not tbl then return end
  
  for applicant, count in pairsByKeys(tbl) do

    -- Gives me my applicant Name
    tmpKey = string.gsub( applicant, "tmp_" , "");
  
    -- If our Applicant doesn't exist create the table
    if not(addon.db.global.applicantQueue[tmpKey])then
      addon.db.global.applicantQueue[tmpKey] = 0
    end 

  end
  
end

function RecruitmentEnhancement:LogWhispers(message, applicant, isFromMe)

  if not(addon.db.global.enableWhisperLogging == true)then return end

  -- Make sure we have our latest Applicants
  RecruitmentEnhancement:BuildApplicantList()
  
  -- define our parties
  if(isFromMe == true)then
    sender = UnitName("player")
    recipient = applicant
  else
    sender = applicant
    recipient = UnitName("player")
  end
  
  -- Are they an applicant or are they me?
  if not (allApplicants[applicant]) then return end
  
  -- Get our Current Time
  curtime = RecruitmentEnhancement:GetCurrentTime()
  
  -- Should I Finish the Convo?
  if(addon.db.global.applicantConvo[applicant] and curtime > addon.db.global.applicantConvo[applicant].endtime)then
    -- End Convo
    RecruitmentEnhancement:LogApplicationAction(applicant,L["Whisper Conversation"],RecruitmentEnhancement:ConvertConverstationToLog(applicant))
    -- Remove it then
    addon.db.global.applicantConvo[applicant] = nil
  end
  
  -- Is there an active conversation?
  if not (addon.db.global.applicantConvo[applicant])then
    addon.db.global.applicantConvo[applicant] = {
      startOfConvo = RecruitmentEnhancement:GetCurrentTimeNice(true),
      endtime = curtime + 300, -- Set our key to 5mins
      whatWasSaid = {}
    }
  end
  
  -- Add our Convo Message
  addon.db.global.applicantConvo[applicant].whatWasSaid[curtime] = {
    sentFrom = sender,
    sentTo = recipient,
    sentTime = RecruitmentEnhancement:GetCurrentTimeNice(true),
    sentMsg = message
  }
  
end

function RecruitmentEnhancement:ConvertConverstationToLog(sender)
  
  tmpConvo = string.upper(L["Whisper Conversation"] .. "\n\n")
  
  if(addon.db.global.applicantConvo[sender].whatWasSaid)then
    for key,value in pairsByKeys(addon.db.global.applicantConvo[sender].whatWasSaid) do
      sentFrom = value.sentFrom
      sentTo = value.sentTo
      sentTime = value.sentTime
      sentMsg = value.sentMsg
      
      tmpConvo = tmpConvo .. sentTime .. " [" .. sentFrom .. "]: " .. sentMsg .. "\n"
      
    end
  end
  
  return tmpConvo
end

function RecruitmentEnhancement:CleanUpConvos()

  -- Get our Current Time
  curtime = RecruitmentEnhancement:GetCurrentTime()
  
  if(addon.db.global.applicantConvo)then
    for key,value in pairsByKeys(addon.db.global.applicantConvo) do
      
      -- Should I Finish the Convo?
      if(curtime > value.endtime)then
        -- End Convo
        RecruitmentEnhancement:LogApplicationAction(key,L["Whisper Conversation"],RecruitmentEnhancement:ConvertConverstationToLog(key))
        -- Remove it then
        addon.db.global.applicantConvo[key] = nil
      end
    
    end
  end

end

--|| UI FRAME ||--
function RecruitmentEnhancement:ReloadCorrespondenceFrame()
  CorrespondenceFrame:Hide()
  CorrespondenceFrame:Hide()
  CorrespondenceFrameShown = 0
  RecruitmentEnhancement:ShowCorrespondenceFrame()
end

function RecruitmentEnhancement:ShowCorrespondenceFrame()

  -- Hide the Frame if it's open already
  if CorrespondenceFrameShown == 1 then
    CorrespondenceFrame:Hide()
    -- CorrespondenceFrame:Hide()
    CorrespondenceFrameShown = 0
  end
  
  if not(GuildFrame:IsShown()) then return end
  if not(GuildInfoFrame:IsShown()) then return end

  local selectedTab = PanelTemplates_GetSelectedTab(GuildInfoFrame);

  -- Show Frame
  if ( selectedTab == 3 ) then

    defaultStatusText = L["Recruitment Enhancement"]

    CorrespondenceFrame = AceGUI:Create("Frame")
    CorrespondenceFrame:SetTitle(L["Recruitment Enhancement"])
    CorrespondenceFrame:SetWidth(375)
    CorrespondenceFrame:SetHeight(430)
    CorrespondenceFrame:SetStatusText(defaultStatusText)
    CorrespondenceFrame:SetLayout("Flow")
    CorrespondenceFrame:SetPoint("CENTER", GuildInfoFrameApplicants, "RIGHT", 200, 20)
    -- CorrespondenceFrame:SetPoint("CENTER", nil, "RIGHT", 190, 20)
    CorrespondenceFrame:SetCallback("OnClose",
      function(widget)
        CorrespondenceFrameShown = 0
      end
    )

    -- If no CurrentView then just use Default
    if not(currentView) then currentView = "Default" end

    -- Default View (front page and ViewToon
    if(currentView == "Default" or currentView == "ViewToon" or currentView == "ConfirmDecline")then
    
      local spacer = AceGUI:Create("Label")
      spacer:SetText("  ")
      spacer:SetWidth(10)
      CorrespondenceFrame:AddChild(spacer)

      local InviteAllIcon = AceGUI:Create("Icon")
      InviteAllIcon:SetImage("Interface\\AddOns\\recruitmentenhancement\\Icons\\inviteall.tga")
      InviteAllIcon:SetImageSize(24,24)
      InviteAllIcon:SetWidth(24)
      InviteAllIcon:SetCallback("OnClick",
        function(widget)
          tbl = {}
          msg = nil
          numApplicants = GetNumGuildApplicants()
          for i = 1, numApplicants do
            local name, level, class, _, _, _, _, _, isTank, isHealer, isDamage, comment = GetGuildApplicantInfo(i);
            tbl[name] = name
            i = i+1
          end
          msg = RecruitmentEnhancement:GuildInviteTable(tbl)
          if(msg)then
            DEFAULT_CHAT_FRAME:AddMessage(msg)
          end
          RecruitmentEnhancement:ShowCorrespondenceFrame()
        end
      )
      InviteAllIcon:SetCallback("OnEnter",
        function(widget)
          CorrespondenceFrame:SetStatusText(L["Invite All Online Applicants"])
        end
      )
      InviteAllIcon:SetCallback("OnLeave",
        function(widget)
          CorrespondenceFrame:SetStatusText(defaultStatusText)
        end
      )
      CorrespondenceFrame:AddChild(InviteAllIcon)
      
      local spacer = AceGUI:Create("Label")
      spacer:SetText("  ")
      spacer:SetWidth(30)
      CorrespondenceFrame:AddChild(spacer)

      local DeclineAllIcon = AceGUI:Create("Icon")
      DeclineAllIcon:SetImage("Interface\\AddOns\\recruitmentenhancement\\Icons\\declineall.tga")
      DeclineAllIcon:SetImageSize(24,24)
      DeclineAllIcon:SetWidth(24)
      DeclineAllIcon:SetCallback("OnClick",
        function(widget)
          currentView = "ConfirmDecline"
          RecruitmentEnhancement:ShowCorrespondenceFrame()
        end
      )
      DeclineAllIcon:SetCallback("OnEnter",
        function(widget)
          CorrespondenceFrame:SetStatusText(L["Decline All Applicants"])
        end
      )
      DeclineAllIcon:SetCallback("OnLeave",
        function(widget)
          CorrespondenceFrame:SetStatusText(defaultStatusText)
        end
      )
      CorrespondenceFrame:AddChild(DeclineAllIcon)

      local spacer = AceGUI:Create("Label")
      spacer:SetText("  ")
      spacer:SetWidth(180)
      CorrespondenceFrame:AddChild(spacer)

      local ArchiveIcon = AceGUI:Create("Icon")
      ArchiveIcon:SetImage("Interface\\AddOns\\recruitmentenhancement\\Icons\\archive.tga")
      ArchiveIcon:SetImageSize(24,24)
      ArchiveIcon:SetWidth(24)
      ArchiveIcon:SetCallback("OnClick",
        function(widget)
          -- Archive
          currentView = "ViewArchive"
          RecruitmentEnhancement:ShowCorrespondenceFrame()
        end
      )
      ArchiveIcon:SetCallback("OnEnter",
        function(widget)
          CorrespondenceFrame:SetStatusText(L["Open Applicant Archives"])
        end
      )
      ArchiveIcon:SetCallback("OnLeave",
        function(widget)
          CorrespondenceFrame:SetStatusText(defaultStatusText)
        end
      )
      CorrespondenceFrame:AddChild(ArchiveIcon)

      local TemplatesIcon = AceGUI:Create("Icon")
      TemplatesIcon:SetImage("Interface\\AddOns\\recruitmentenhancement\\Icons\\templates.tga")
      TemplatesIcon:SetImageSize(24,24)
      TemplatesIcon:SetWidth(24)
      TemplatesIcon:SetCallback("OnClick",
        function(widget)
          -- Archive
          currentView = "ViewTemplate"
          RecruitmentEnhancement:ShowCorrespondenceFrame()
        end
      )
      TemplatesIcon:SetCallback("OnEnter",
        function(widget)
          CorrespondenceFrame:SetStatusText(L["Manage Templates"])
        end
      )
      TemplatesIcon:SetCallback("OnLeave",
        function(widget)
          CorrespondenceFrame:SetStatusText(defaultStatusText)
        end
      )
      CorrespondenceFrame:AddChild(TemplatesIcon)
      
      local ConfigIcon = AceGUI:Create("Icon")
      ConfigIcon:SetImage("Interface\\AddOns\\recruitmentenhancement\\Icons\\config.tga")
      ConfigIcon:SetImageSize(24,24)
      ConfigIcon:SetWidth(24)
      ConfigIcon:SetCallback("OnClick",
        function(widget)
          currentView = "ViewConfig"
          RecruitmentEnhancement:ShowCorrespondenceFrame()
        end
      )
      ConfigIcon:SetCallback("OnEnter",
        function(widget)
          CorrespondenceFrame:SetStatusText(L["Addon Configuration"])
        end
      )
      ConfigIcon:SetCallback("OnLeave",
        function(widget)
          CorrespondenceFrame:SetStatusText(defaultStatusText)
        end
      )
      CorrespondenceFrame:AddChild(ConfigIcon)

      -- Second Line

      currentSelection = GetGuildApplicantSelection()
      local name, level, class, _, _, _, _, _, isTank, isHealer, isDamage, _,_,comment = GetGuildApplicantInfo(currentSelection);

      if(addon.db.global.autoAddRemoveToons == true)then
        if not(friends[name])then
          if(name and liac:GetCooldown("RecruitmentEnhancement", "InviteBlocked", name ) == 0)then
            AddFriend(name, friendsMessage )
            ShowFriends()
          end
        end
      end

      if(currentSelection == 0 or currentSelection == nil)then
      
        --[[
        InviteOneIcon:SetDisabled(true)
        DeclineOneIcon:SetDisabled(true)
        WhisperIcon:SetDisabled(true)
        ]]

      else

        if not (addon.db.global.recruitLog[name])then
          addon.db.global.recruitLog[name] = { sentMail = {} }
        end

        if not(currentView == "ConfirmDecline")then
          currentView = "ViewToon"
        end

      end

      if not (name or currentView == "ConfirmDecline") then currentView = "Default" end

      if(currentView == "Default")then

        local about_title = AceGUI:Create("Heading")
        about_title:SetText(L["About Recruitment Enhancement Version"] .. " " .. version)
        about_title:SetFullWidth(true)
        CorrespondenceFrame:AddChild(about_title)
        
        local ConfigFrame =  AceGUI:Create("ScrollFrame")
        ConfigFrame:SetLayout("Flow")
        ConfigFrame:SetFullWidth(true)
        ConfigFrame:SetFullHeight(true)
        CorrespondenceFrame:AddChild(ConfigFrame)
        
        if(localeStatus[playerLocale] == false)then
          local locale = AceGUI:Create("Label")
          locale:SetText("|cff00ff00" .. L["Locale Warning"] .. "|r\n")
          locale:SetFont("Fonts\\FRIZQT__.TTF", 15, "OUTLINE")
          locale:SetRelativeWidth(1.0)
          ConfigFrame:AddChild(locale)
        end

        local description = AceGUI:Create("Label")
        description:SetText(string.format(L["Addon Description"],L["Recruitment Enhancement"],version))
        description:SetFont("Fonts\\FRIZQT__.TTF", 12, nil)
        description:SetRelativeWidth(1.0)
        ConfigFrame:AddChild(description)

      end

      if(currentView == "ConfirmDecline")then

        local about_title = AceGUI:Create("Heading")
        about_title:SetText(L["Confirm Decline All Applications"])
        about_title:SetFullWidth(true)
        CorrespondenceFrame:AddChild(about_title)

        local description = AceGUI:Create("Label")
        description:SetText("\n\n|cffff8800" .. L["Are you sure you want to decline ALL applicants? This can't be undone!"] .. "|r\n\n")
        description:SetFont("Fonts\\FRIZQT__.TTF", 18, nil)
        description:SetRelativeWidth(1.0)
        CorrespondenceFrame:AddChild(description)
        
        local yes = AceGUI:Create("Button")
        yes:SetText("YES DO IT!!")
        yes:SetRelativeWidth(0.5)
        yes:SetCallback("OnClick", function()
          numApplicants = GetNumGuildApplicants()
          for i = 1, numApplicants do
            local name, level, class, _, _, _, _, _, isTank, isHealer, isDamage, comment = GetGuildApplicantInfo(i);
            remName = name
            DeclineGuildApplicant(i);
            RecruitmentEnhancement:QueueRemove(name,"gui confirm")
            if(addon.db.global.autoAddRemoveToons == true)then
              liac:AddCooldown("RecruitmentEnhancement", "InviteBlocked", remName, 15)
              RemoveFriend(remName)
            end
            i = i+1
          end
          currentView = nil
          currentSelectedToon = nil
          RecruitmentEnhancement:ReloadCorrespondenceFrame()
          RecruitmentEnhancement:ShowCorrespondenceFrame()
        end)
        CorrespondenceFrame:AddChild(yes)
        
        local no = AceGUI:Create("Button")
        no:SetText("NO!!! :(")
        no:SetRelativeWidth(0.5)
        no:SetCallback("OnClick", function()
          currentView = nil
          currentSelectedToon = nil
          RecruitmentEnhancement:ReloadCorrespondenceFrame()
          RecruitmentEnhancement:ShowCorrespondenceFrame()
        end)
        CorrespondenceFrame:AddChild(no)

      end
      
      if(currentView == "ViewToon")then
      
        status,area = RecruitmentEnhancement:CheckOnlineStatus(name)

        if(addon.db.global.autoSyncSelectedApplicantActive == true)then
          self:SendCommMessage("REnhRequest", name, "OFFICER")
        end

        onlineStatus = "online.tga"
        onlineStatusText = L["Currently Online"]
        
        if not area then
          area = "Unknown"
        end
        
        if(addon.db.global.autoAddRemoveToons == true and status == nil)then
          onlineStatus = "offline.tga"
          onlineStatusText = L["Currently Offline"]
        end
        if(addon.db.global.autoAddRemoveToons == false)then
          onlineStatus = "unknown.tga"
          onlineStatusText = L["Detection is Disabled"]
        end

        local toon_title = AceGUI:Create("Heading")
        toon_title:SetText(name .. " " .. L["Details"])
        toon_title:SetFullWidth(true)
        CorrespondenceFrame:AddChild(toon_title)

        local OnlineStatusIcon = AceGUI:Create("Icon")
        OnlineStatusIcon:SetImage("Interface\\AddOns\\recruitmentenhancement\\Icons\\" .. onlineStatus)
        OnlineStatusIcon:SetImageSize(24,24)
        OnlineStatusIcon:SetWidth(24)
        OnlineStatusIcon:SetCallback("OnEnter",
          function(widget)
            CorrespondenceFrame:SetStatusText(string.format(L["Applicant Online Status"],onlineStatusText))
          end
        )
        OnlineStatusIcon:SetCallback("OnLeave",
          function(widget)
            CorrespondenceFrame:SetStatusText(defaultStatusText)
          end
        )
        CorrespondenceFrame:AddChild(OnlineStatusIcon)
        
        local OnlineAreaIcon = AceGUI:Create("Icon")
        OnlineAreaIcon:SetImage("Interface\\AddOns\\recruitmentenhancement\\Icons\\find.tga")
        OnlineAreaIcon:SetImageSize(24,24)
        OnlineAreaIcon:SetWidth(24)
        OnlineAreaIcon:SetCallback("OnEnter",
          function(widget)
            CorrespondenceFrame:SetStatusText(area)
          end
        )
        OnlineAreaIcon:SetCallback("OnLeave",
          function(widget)
            CorrespondenceFrame:SetStatusText(defaultStatusText)
          end
        )
        CorrespondenceFrame:AddChild(OnlineAreaIcon)
        
        local spacer = AceGUI:Create("Label")
        spacer:SetText("  ")
        spacer:SetWidth(38)
        CorrespondenceFrame:AddChild(spacer)
        
        -- Show either the Queued / Invite Icon
        if(RecruitmentEnhancement:QueueCheck(name) == true)then

          local QueuedIcon = AceGUI:Create("Icon")
          QueuedIcon:SetImage("Interface\\AddOns\\recruitmentenhancement\\Icons\\appqueued.tga")
          QueuedIcon:SetImageSize(24,24)
          QueuedIcon:SetWidth(24)
          QueuedIcon:SetCallback("OnEnter",
            function(widget)
              CorrespondenceFrame:SetStatusText(L["Applicant Already Queued for Invite"])
            end
          )
          QueuedIcon:SetCallback("OnLeave",
            function(widget)
              CorrespondenceFrame:SetStatusText(defaultStatusText)
            end
          )
          CorrespondenceFrame:AddChild(QueuedIcon)

        else

          local InviteOneIcon = AceGUI:Create("Icon")
          InviteOneIcon:SetImage("Interface\\AddOns\\recruitmentenhancement\\Icons\\inviteone.tga")
          InviteOneIcon:SetImageSize(24,24)
          InviteOneIcon:SetWidth(24)
          InviteOneIcon:SetCallback("OnClick",
            function(widget)
              tbl = {}
              msg = nil
              currentSelection = GetGuildApplicantSelection()
              local name, level, class, _, _, _, _, _, isTank, isHealer, isDamage, comment = GetGuildApplicantInfo(currentSelection);
              if(name) then
                tbl[name] = name
                msg = RecruitmentEnhancement:GuildInviteTable(tbl)
                if(msg)then
                  DEFAULT_CHAT_FRAME:AddMessage(msg)
                end
              end
              RecruitmentEnhancement:ShowCorrespondenceFrame()
            end
          )
          InviteOneIcon:SetCallback("OnEnter",
            function(widget)
              CorrespondenceFrame:SetStatusText(L["Invite Selected Applicant"])
            end
          )
          InviteOneIcon:SetCallback("OnLeave",
            function(widget)
              CorrespondenceFrame:SetStatusText(defaultStatusText)
            end
          )
          CorrespondenceFrame:AddChild(InviteOneIcon)
          
        end

        local DeclineOneIcon = AceGUI:Create("Icon")
        DeclineOneIcon:SetImage("Interface\\AddOns\\recruitmentenhancement\\Icons\\declineone.tga")
        DeclineOneIcon:SetImageSize(24,24)
        DeclineOneIcon:SetWidth(24)
        DeclineOneIcon:SetCallback("OnClick",
          function(widget)
            appId = GetGuildApplicantSelection()
            local name, level, class, _, _, _, _, _, isTank, isHealer, isDamage, comment = GetGuildApplicantInfo(appId);
            remName = name
            DeclineGuildApplicant(appId);
            RecruitmentEnhancement:QueueRemove(remName,"gui decline 1")
            if(addon.db.global.autoAddRemoveToons == true)then
              liac:AddCooldown("RecruitmentEnhancement", "InviteBlocked", remName, 15)
              RemoveFriend(remName)
              ShowFriends()
            end
            RecruitmentEnhancement:ShowCorrespondenceFrame()
          end
        )
        DeclineOneIcon:SetCallback("OnEnter",
          function(widget)
            CorrespondenceFrame:SetStatusText(L["Decline Selected Applicant"])
          end
        )
        DeclineOneIcon:SetCallback("OnLeave",
          function(widget)
            CorrespondenceFrame:SetStatusText(defaultStatusText)
          end
        )
        CorrespondenceFrame:AddChild(DeclineOneIcon)
        
        local spacer = AceGUI:Create("Label")
        spacer:SetText("  ")
        spacer:SetWidth(38)
        CorrespondenceFrame:AddChild(spacer)

        local WhisperIcon = AceGUI:Create("Icon")
        WhisperIcon:SetImage("Interface\\AddOns\\recruitmentenhancement\\Icons\\whisper.tga")
        WhisperIcon:SetImageSize(24,24)
        WhisperIcon:SetWidth(24)
        WhisperIcon:SetCallback("OnClick",
          function(widget)
            currentSelection = GetGuildApplicantSelection()
            local name, level, class, _, _, _, _, _, isTank, isHealer, isDamage, comment = GetGuildApplicantInfo(currentSelection);
            if(name) then
              ChatFrame_SendTell(name);
            end
          end
        )
        WhisperIcon:SetCallback("OnEnter",
          function(widget)
            CorrespondenceFrame:SetStatusText(L["Whisper Applicant"])
          end
        )
        WhisperIcon:SetCallback("OnLeave",
          function(widget)
            CorrespondenceFrame:SetStatusText(defaultStatusText)
          end
        )
        CorrespondenceFrame:AddChild(WhisperIcon)

        local MailIcon = AceGUI:Create("Icon")
        MailIcon:SetImage("Interface\\AddOns\\recruitmentenhancement\\Icons\\mail.tga")
        MailIcon:SetImageSize(24,24)
        MailIcon:SetWidth(24)
        MailIcon:SetCallback("OnClick",
          function(widget)
            RecruitmentEnhancement:PopulateRecruitMail();
            MailFrameTab2:Click()
          end
        )
        MailIcon:SetCallback("OnEnter",
          function(widget)
            CorrespondenceFrame:SetStatusText(L["Mail with Selected Template"])
          end
        )
        MailIcon:SetCallback("OnLeave",
          function(widget)
            CorrespondenceFrame:SetStatusText(defaultStatusText)
          end
        )
        CorrespondenceFrame:AddChild(MailIcon)

        pulldown = RecruitmentEnhancement:GetMailTemplatePulldown()

        local dropdown = AceGUI:Create("Dropdown")
        dropdown:SetWidth(115)
        dropdown:SetList(pulldown)
        dropdown:SetLabel(" ")
        dropdown:SetValue(addon.db.global.selectedMailTemplate)
        dropdown:SetCallback("OnValueChanged", function()
          addon.db.global.selectedMailTemplate = dropdown.value
        end)
        CorrespondenceFrame:AddChild(dropdown)

        local spacer = AceGUI:Create("Label")
        spacer:SetText("  ")
        spacer:SetWidth(10)
        CorrespondenceFrame:AddChild(spacer)

        local correspondance = AceGUI:Create("MultiLineEditBox")
        tmpCorrespondence = RecruitmentEnhancement:BuildRecruitCorrespondence(name,comment)
        correspondance:SetText(tmpCorrespondence)
        correspondance:SetLabel(L["Application Comment & Correspondence"])
        correspondance:SetFullWidth(true)
        correspondance:SetHeight(230)
        CorrespondenceFrame:AddChild(correspondance)

        -- Make our Checks and Disabled Icons as Required
        if(addon.db.global.autoAddRemoveToons == true and addon.db.global.enableInviteQueue == false and status == nil)then
          if(InviteOneIcon)then InviteOneIcon:SetDisabled(true) end
        end
        
        if(addon.db.global.autoAddRemoveToons == true and status == nil)then
          if(WhisperIcon)then WhisperIcon:SetDisabled(true) end
        end
        
        if(status == nil)then
          if(OnlineAreaIcon)then OnlineAreaIcon:SetDisabled(true) end
        end
        
        if(mailIsOpen == false or currentSelection == 0)then
          if(MailIcon)then MailIcon:SetDisabled(true) end
        end

      end

    end

    -- If Current View is ViewArchive
    if(currentView == "ViewArchive")then

      local BackIcon = AceGUI:Create("Icon")
      BackIcon:SetImage("Interface\\AddOns\\recruitmentenhancement\\Icons\\back.tga")
      BackIcon:SetImageSize(24,24)
      BackIcon:SetWidth(24)
      BackIcon:SetCallback("OnClick",
        function(widget)
          -- Archive
          currentView = nil
          currentSelectedToon = nil
          RecruitmentEnhancement:ReloadCorrespondenceFrame()
        end
      )
      BackIcon:SetCallback("OnEnter",
        function(widget)
          CorrespondenceFrame:SetStatusText(L["Return to Main Panel"])
        end
      )
      BackIcon:SetCallback("OnLeave",
        function(widget)
          CorrespondenceFrame:SetStatusText(defaultStatusText)
        end
      )
      CorrespondenceFrame:AddChild(BackIcon)

      local spacer = AceGUI:Create("Label")
      spacer:SetText("  ")
      spacer:SetWidth(70)
      CorrespondenceFrame:AddChild(spacer)

      pulldown = RecruitmentEnhancement:GetApplicantArchivePulldown()

      local dropdown = AceGUI:Create("Dropdown")
      dropdown:SetWidth(200)
      dropdown:SetList(pulldown)
      dropdown:SetLabel(" ")
      dropdown:SetValue(currentSelectedToon)
      dropdown:SetCallback("OnValueChanged", function()
        currentSelectedToon = dropdown.value
        if(addon.db.global.autoSyncSelectedApplicantArchive == true)then
          self:SendCommMessage("REnhRequest", currentSelectedToon, "OFFICER")
        end
        RecruitmentEnhancement:ReloadCorrespondenceFrame()
      end)
      CorrespondenceFrame:AddChild(dropdown)

      local DeleteIcon = AceGUI:Create("Icon")
      DeleteIcon:SetImage("Interface\\AddOns\\recruitmentenhancement\\Icons\\declineall.tga")
      DeleteIcon:SetImageSize(24,24)
      DeleteIcon:SetWidth(24)
      DeleteIcon:SetCallback("OnClick",
        function(widget)
          if(currentSelectedToon)then
            addon.db.global.recruitLog[currentSelectedToon] = nil
            currentSelectedToon = nil
            RecruitmentEnhancement:ReloadCorrespondenceFrame()
          end
        end
      )
      DeleteIcon:SetCallback("OnEnter",
        function(widget)
          CorrespondenceFrame:SetStatusText(L["Delete Applicant Correspondence"])
        end
      )
      DeleteIcon:SetCallback("OnLeave",
        function(widget)
          CorrespondenceFrame:SetStatusText(defaultStatusText)
        end
      )
      CorrespondenceFrame:AddChild(DeleteIcon)

      local correspondance = AceGUI:Create("MultiLineEditBox")
      tmpCorrespondence = RecruitmentEnhancement:BuildRecruitCorrespondence(currentSelectedToon)
      if not tmpCorrespondence then tmpCorrespondence = L["Select Applicant"]  end
      correspondance:SetText(tmpCorrespondence)
      correspondance:SetLabel(L["Correspondence"])
      correspondance:SetFullWidth(true)
      correspondance:SetHeight(300)
      CorrespondenceFrame:AddChild(correspondance)

      if(currentSelectedToon == nil)then
        DeleteIcon:SetDisabled(true)
      end

    end
    
    -- If Current View is ViewTemplate
    if(currentView == "ViewTemplate")then

      local BackIcon = AceGUI:Create("Icon")
      BackIcon:SetImage("Interface\\AddOns\\recruitmentenhancement\\Icons\\back.tga")
      BackIcon:SetImageSize(24,24)
      BackIcon:SetWidth(24)
      BackIcon:SetCallback("OnClick",
        function(widget)
          -- Archive
          currentView = nil
          currentSelectedToon = nil
          RecruitmentEnhancement:ReloadCorrespondenceFrame()
        end
      )
      BackIcon:SetCallback("OnEnter",
        function(widget)
          CorrespondenceFrame:SetStatusText(L["Return to Main Panel"])
        end
      )
      BackIcon:SetCallback("OnLeave",
        function(widget)
          CorrespondenceFrame:SetStatusText(defaultStatusText)
        end
      )
      CorrespondenceFrame:AddChild(BackIcon)

      local spacer = AceGUI:Create("Label")
      spacer:SetText("  ")
      spacer:SetWidth(20)
      CorrespondenceFrame:AddChild(spacer)

      local newtemplate = AceGUI:Create("EditBox")
      newtemplate:SetLabel("")
      newtemplate:SetWidth(130)
      newtemplate:SetText("New Template")
      newtemplate:SetCallback("OnEnterPressed", function(widget, event, text)
        if(text and text ~= "New Template")then
          if not (addon.db.global.mailTemplates[text]) then
            addon.db.global.mailTemplates[text] = {
              subject = L["Default Subject for {guild}!"],
              body = L["Default Body whooop"]
            }
          end
          currentSelectedTemplate = text
          RecruitmentEnhancement:ReloadCorrespondenceFrame()
        end
      end)
      CorrespondenceFrame:AddChild(newtemplate)

      pulldown = RecruitmentEnhancement:GetMailTemplatePulldown()

      local dropdown = AceGUI:Create("Dropdown")
      dropdown:SetWidth(130)
      dropdown:SetList(pulldown)
      dropdown:SetLabel(" ")
      dropdown:SetValue(currentSelectedTemplate)
      dropdown:SetCallback("OnValueChanged", function()
        currentSelectedTemplate = dropdown.value
        RecruitmentEnhancement:ReloadCorrespondenceFrame()
      end)
      CorrespondenceFrame:AddChild(dropdown)

      local DeleteIcon = AceGUI:Create("Icon")
      DeleteIcon:SetImage("Interface\\AddOns\\recruitmentenhancement\\Icons\\declineall.tga")
      DeleteIcon:SetImageSize(24,24)
      DeleteIcon:SetWidth(24)
      DeleteIcon:SetCallback("OnClick",
        function(widget)
          if(currentSelectedTemplate)then
            addon.db.global.mailTemplates[currentSelectedTemplate] = nil
            currentSelectedTemplate = nil
            RecruitmentEnhancement:ReloadCorrespondenceFrame()
          end
        end
      )
      DeleteIcon:SetCallback("OnEnter",
        function(widget)
          CorrespondenceFrame:SetStatusText(L["Delete Applicant Correspondence"])
        end
      )
      DeleteIcon:SetCallback("OnLeave",
        function(widget)
          CorrespondenceFrame:SetStatusText(defaultStatusText)
        end
      )
      CorrespondenceFrame:AddChild(DeleteIcon)

      if(currentSelectedTemplate)then
        subject = addon.db.global.mailTemplates[currentSelectedTemplate].subject
        body = addon.db.global.mailTemplates[currentSelectedTemplate].body
      else
        subject = L["Add or Manage a Template"]
        body = nil
      end

      local subjectForm = AceGUI:Create("EditBox")
      subjectForm:SetLabel(L["Subject"])
      subjectForm:SetFullWidth(true)
      subjectForm:SetText(subject)
      subjectForm:SetCallback("OnEnterPressed", function(widget, event, text)
        if(currentSelectedTemplate)then
          addon.db.global.mailTemplates[currentSelectedTemplate].subject = text
        end
      end)
      CorrespondenceFrame:AddChild(subjectForm)

      local bodyForm = AceGUI:Create("MultiLineEditBox")
      if body ~= nil then bodyForm:SetText(body) end
      bodyForm:SetLabel(string.format(L["Template Body (use: {player} {rank} {guild} {guilurl} )"], L["{guild}"] , L["{guildurl}"], L["{player}"],L["{rank}"]))
      bodyForm:SetFullWidth(true)
      bodyForm:SetHeight(250)
      bodyForm:SetCallback("OnEnterPressed", function(widget, event, text)
        addon.db.global.mailTemplates[currentSelectedTemplate].body = text
      end)
      CorrespondenceFrame:AddChild(bodyForm)

      if(currentSelectedTemplate == nil)then
        DeleteIcon:SetDisabled(true)
      end

    end
    
    -- If Current View is ViewConfig
    if(currentView == "ViewConfig")then

      local BackIcon = AceGUI:Create("Icon")
      BackIcon:SetImage("Interface\\AddOns\\recruitmentenhancement\\Icons\\back.tga")
      BackIcon:SetImageSize(24,24)
      BackIcon:SetWidth(24)
      BackIcon:SetCallback("OnClick",
        function(widget)
          -- Archive
          currentView = nil
          currentSelectedToon = nil
          RecruitmentEnhancement:ReloadCorrespondenceFrame()
        end
      )
      BackIcon:SetCallback("OnEnter",
        function(widget)
          CorrespondenceFrame:SetStatusText(L["Return to Main Panel"])
        end
      )
      BackIcon:SetCallback("OnLeave",
        function(widget)
          CorrespondenceFrame:SetStatusText(defaultStatusText)
        end
      )
      CorrespondenceFrame:AddChild(BackIcon)
      
      -- Create the ScrollFrame JUST IN CASE
      local ConfigFrame =  AceGUI:Create("ScrollFrame")
      ConfigFrame:SetLayout("Flow")
      ConfigFrame:SetFullWidth(true)
      ConfigFrame:SetFullHeight(true)
      CorrespondenceFrame:AddChild(ConfigFrame)
      
      local title = AceGUI:Create("Heading")
      title:SetText(L["Basic Settings"])
      title:SetFullWidth(true)
      ConfigFrame:AddChild(title)

      local autoAddRemoveToons = AceGUI:Create("CheckBox")
      autoAddRemoveToons:SetLabel(L["Online Scanner"])
      autoAddRemoveToons:SetDescription(L["Online Scanner Description"])
      autoAddRemoveToons:SetFullWidth(true)
      autoAddRemoveToons:SetType("checkbox")
      if(addon.db.global.autoAddRemoveToons == true) then
        autoAddRemoveToons:SetValue(true)
      else
        autoAddRemoveToons:SetValue(false)
      end
      autoAddRemoveToons:SetCallback("OnValueChanged", function(widget, event, text)
        addon.db.global.autoAddRemoveToons = text
      end)
      ConfigFrame:AddChild(autoAddRemoveToons)
      
      local enableWhisperLogging = AceGUI:Create("CheckBox")
      enableWhisperLogging:SetLabel(L["Enable Whisper Logging"])
      enableWhisperLogging:SetDescription(L["Will log whispers between you and the applicant and add them to your log"])
      enableWhisperLogging:SetFullWidth(true)
      enableWhisperLogging:SetType("checkbox")
      if(addon.db.global.enableWhisperLogging == true) then
        enableWhisperLogging:SetValue(true)
      else
        enableWhisperLogging:SetValue(false)
      end
      enableWhisperLogging:SetCallback("OnValueChanged", function(widget, event, text)
        addon.db.global.enableWhisperLogging = text
        if(text == true)then
          self:RegisterEvent("CHAT_MSG_WHISPER");
          self:RegisterEvent("CHAT_MSG_WHISPER_INFORM");
        else
          self:UnregisterEvent("CHAT_MSG_WHISPER");
          self:UnregisterEvent("CHAT_MSG_WHISPER_INFORM");
        end
      end)
      ConfigFrame:AddChild(enableWhisperLogging)
      
      local enableBellSound = AceGUI:Create("CheckBox")
      enableBellSound:SetLabel(L["New Applicant Alert Sound"])
      enableBellSound:SetDescription(L["New Applicant Alert Sound Description"])
      enableBellSound:SetFullWidth(true)
      enableBellSound:SetType("checkbox")
      if(addon.db.global.enableBellSound == true) then
        enableBellSound:SetValue(true)
      else
        enableBellSound:SetValue(false)
      end
      enableBellSound:SetCallback("OnValueChanged", function(widget, event, text)
        addon.db.global.enableBellSound = text
      end)
      ConfigFrame:AddChild(enableBellSound)
      
      local autoClearEmtpyApplicantArchive = AceGUI:Create("CheckBox")
      autoClearEmtpyApplicantArchive:SetLabel(L["Auto Clear Empty Applicant Archives"])
      autoClearEmtpyApplicantArchive:SetDescription(L["Auto Clear Empty Applicant Archives Description"])
      autoClearEmtpyApplicantArchive:SetFullWidth(true)
      autoClearEmtpyApplicantArchive:SetType("checkbox")
      if(addon.db.global.autoClearEmtpyApplicantArchive == true) then
        autoClearEmtpyApplicantArchive:SetValue(true)
      else
        autoClearEmtpyApplicantArchive:SetValue(false)
      end
      autoClearEmtpyApplicantArchive:SetCallback("OnValueChanged", function(widget, event, text)
        addon.db.global.autoClearEmtpyApplicantArchive = text
      end)
      ConfigFrame:AddChild(autoClearEmtpyApplicantArchive)
      
      local enableInviteQueue = AceGUI:Create("CheckBox")
      enableInviteQueue:SetLabel(L["Enable Invite Queue"])
      enableInviteQueue:SetDescription(L["Enable Invite Queue Description"])
      enableInviteQueue:SetFullWidth(true)
      enableInviteQueue:SetType("checkbox")
      if(addon.db.global.enableInviteQueue == true) then
        enableInviteQueue:SetValue(true)
      else
        enableInviteQueue:SetValue(false)
      end
      enableInviteQueue:SetCallback("OnValueChanged", function(widget, event, text)
        addon.db.global.enableInviteQueue = text
      end)
      ConfigFrame:AddChild(enableInviteQueue)
      
      local enableAutoWhisper = AceGUI:Create("CheckBox")
      enableAutoWhisper:SetLabel(L["Auto Whisper Invited Applicants"])
      enableAutoWhisper:SetDescription(L["Auto Whisper Invited Applicants Description"])
      enableAutoWhisper:SetFullWidth(true)
      enableAutoWhisper:SetType("checkbox")
      if(addon.db.global.enableAutoWhisper == true) then
        enableAutoWhisper:SetValue(true)
      else
        enableAutoWhisper:SetValue(false)
      end
      enableAutoWhisper:SetCallback("OnValueChanged", function(widget, event, text)
        addon.db.global.enableAutoWhisper = text
      end)
      ConfigFrame:AddChild(enableAutoWhisper)
      
      local autoWhisperWelcomeMsg = AceGUI:Create("EditBox")
      autoWhisperWelcomeMsg:SetLabel(L["Auto Whisper Message (use {guild})"])
      autoWhisperWelcomeMsg:SetFullWidth(true)
      autoWhisperWelcomeMsg:SetText(addon.db.global.autoWhisperWelcomeMsg)
      autoWhisperWelcomeMsg:SetCallback("OnEnterPressed", function(widget, event, text)
        addon.db.global.autoWhisperWelcomeMsg = text
      end)
      ConfigFrame:AddChild(autoWhisperWelcomeMsg)
      
      local title = AceGUI:Create("Heading")
      title:SetText(L["Guild and Region Settings"])
      title:SetFullWidth(true)
      ConfigFrame:AddChild(title)

      local guildUrlForm = AceGUI:Create("EditBox")
      guildUrlForm:SetLabel(L["Guild Url"])
      guildUrlForm:SetFullWidth(true)
      guildUrlForm:SetText(addon.db.global.guildUrl)
      guildUrlForm:SetCallback("OnEnterPressed", function(widget, event, text)
        addon.db.global.guildUrl = text
      end)
      ConfigFrame:AddChild(guildUrlForm)
      
      local regionPulldown = AceGUI:Create("Dropdown")
      regionPulldown:SetFullWidth(true)
      regionPulldown:SetList(regionLookup)
      regionPulldown:SetLabel(L["Region"])
      regionPulldown:SetValue(addon.db.global.gameRegion)
      regionPulldown:SetCallback("OnValueChanged", function()
        local selection = regionPulldown.value
        addon.db.global.gameRegion = selection
        addon.db.global.gameLanguage = languageLookup[selection]
      end)
      ConfigFrame:AddChild(regionPulldown)
      
      local languageAlt = AceGUI:Create("EditBox")
      languageAlt:SetLabel(L["Alternative Language"])
      languageAlt:SetFullWidth(true)
      languageAlt:SetText(addon.db.global.gameAltLanguage)
      languageAlt:SetCallback("OnEnterPressed", function(widget, event, text)
        addon.db.global.gameAltLanguage = text
      end)
      ConfigFrame:AddChild(languageAlt)
      
      local title = AceGUI:Create("Heading")
      title:SetText(L["Syncing Settings"])
      title:SetFullWidth(true)
      ConfigFrame:AddChild(title)
      
      local autoSyncSelectedApplicantArchive = AceGUI:Create("CheckBox")
      autoSyncSelectedApplicantArchive:SetLabel(L["Auto Sync Archived App when Selected"])
      autoSyncSelectedApplicantArchive:SetDescription(L["Auto Sync Archived App when Selected Description"])
      autoSyncSelectedApplicantArchive:SetFullWidth(true)
      autoSyncSelectedApplicantArchive:SetType("checkbox")
      if(addon.db.global.autoSyncSelectedApplicantArchive == true) then
        autoSyncSelectedApplicantArchive:SetValue(true)
      else
        autoSyncSelectedApplicantArchive:SetValue(false)
      end
      autoSyncSelectedApplicantArchive:SetCallback("OnValueChanged", function(widget, event, text)
        addon.db.global.autoSyncSelectedApplicantArchive = text
      end)
      ConfigFrame:AddChild(autoSyncSelectedApplicantArchive)
      
      local autoSyncSelectedApplicantActive = AceGUI:Create("CheckBox")
      autoSyncSelectedApplicantActive:SetLabel(L["Auto Sync Active App when Selected"])
      autoSyncSelectedApplicantActive:SetDescription(L["Auto Sync Active App when Selected Description"])
      autoSyncSelectedApplicantActive:SetFullWidth(true)
      autoSyncSelectedApplicantActive:SetType("checkbox")
      if(addon.db.global.autoSyncSelectedApplicantActive == true) then
        autoSyncSelectedApplicantActive:SetValue(true)
      else
        autoSyncSelectedApplicantActive:SetValue(false)
      end
      autoSyncSelectedApplicantActive:SetCallback("OnValueChanged", function(widget, event, text)
        addon.db.global.autoSyncSelectedApplicantActive = text
      end)
      ConfigFrame:AddChild(autoSyncSelectedApplicantActive)
      
      local autoSyncAllCurrentApplicantsOnLogin = AceGUI:Create("CheckBox")
      autoSyncAllCurrentApplicantsOnLogin:SetLabel(L["Auto Sync Current App on Login"])
      autoSyncAllCurrentApplicantsOnLogin:SetDescription(L["Auto Sync Current App on Login Description"])
      autoSyncAllCurrentApplicantsOnLogin:SetFullWidth(true)
      autoSyncAllCurrentApplicantsOnLogin:SetType("checkbox")
      if(addon.db.global.autoSyncAllCurrentApplicantsOnLogin == true) then
        autoSyncAllCurrentApplicantsOnLogin:SetValue(true)
      else
        autoSyncAllCurrentApplicantsOnLogin:SetValue(false)
      end
      autoSyncAllCurrentApplicantsOnLogin:SetCallback("OnValueChanged", function(widget, event, text)
        addon.db.global.autoSyncAllCurrentApplicantsOnLogin = text
      end)
      ConfigFrame:AddChild(autoSyncAllCurrentApplicantsOnLogin)

      local title = AceGUI:Create("Heading")
      title:SetText(L["Debugging Settings (Advanced)"])
      title:SetFullWidth(true)
      ConfigFrame:AddChild(title)
      
      local frameTesting = AceGUI:Create("CheckBox")
      frameTesting:SetLabel(L["Logging for Hide Frame Issues"])
      frameTesting:SetFullWidth(true)
      frameTesting:SetType("checkbox")
      if(addon.db.global.frameTesting == true) then
        frameTesting:SetValue(true)
      else
        frameTesting:SetValue(false)
      end
      frameTesting:SetCallback("OnValueChanged", function(widget, event, text)
        addon.db.global.frameTesting = text
      end)
      ConfigFrame:AddChild(frameTesting)

    end

    CorrespondenceFrameShown = 1
  end
end

--|| GENERIC FUNCTIONS ||--

function RecruitmentEnhancement:GetCurrentTime()
  return time{year=date("%Y"), month=date("%m"), day=date("%d"), hour=date("%H"), min=date("%M"), sec=date("%S")}
end

function RecruitmentEnhancement:GetCurrentTimeNice(flag)

  local hour=date("%H")
  local min=date("%M")
  local sec=date("%S")

  if (flag == true)then
    nicetime = hour .. ":" .. min .. ":" .. sec
  else
    nicetime = hour .. ":" .. min
  end

  return nicetime

end

function RecruitmentEnhancement:GetCurrentDateNice()

  local year=date("%y")
  local month=date("%b")
  local day=date("%d")
  -- local nicedate = year .. "-" .. month .. "-" .. day
  local nicedate = day .. "-" .. month .. "-" .. year
  return nicedate

end

function RecruitmentEnhancement:ConvertTableKeys2CSV(t)

  -- Clear and set Our Comma Stuff
  csv = nil
  comma = false
  -- Loop through the Passed Table
  if(t)then
    for key,value in pairsByKeys(t) do
      if(comma == true)then csv = csv .. " , " end
      if(csv == nil)then csv = key else csv = csv .. key end
      comma = true
    end
  end

  if not(csv)then
    csv = "None"
  end

  return csv

end

function RecruitmentEnhancement:CountTable(t)
  
  tblCount = 0
  if not(t)then return tblCount end -- recipient not in Log

  if(t)then
    for key, value in pairsByKeys(t) do
      tblCount = tblCount + 1
    end
  end

  return tblCount
  
end

function pairsByKeys (t, f)
  local a = {}
  for n in pairs(t) do table.insert(a, n) end
  table.sort(a, f)
  local i = 0      -- iterator variable
  local iter = function ()   -- iterator function
    i = i + 1
    if a[i] == nil then return nil
    else return a[i], t[a[i]]
    end
  end
  return iter
end